<template>
  <el-container class="layout-container">
    <!-- 侧边栏 -->
    <el-aside :width="isCollapse ? '64px' : '220px'" class="aside">
      <!-- Logo区域 -->
      <div class="logo">
        <span class="logo-text" v-show="!isCollapse">超市管理系统</span>
        <span class="logo-text-collapse" v-show="isCollapse">超市</span>
      </div>

      <!-- 菜单 -->
      <el-scrollbar>
        <el-menu class="el-menu-vertical" style="height: 100%;" background-color="#304156" text-color="#bfcbd9"
          active-text-color="#409EFF" router :default-active="activeMenu" :collapse="isCollapse"
          :collapse-transition="false">
          <el-menu-item index="/">
            <el-icon>
              <HomeFilled />
            </el-icon>
            <template #title>首页</template>
          </el-menu-item>

          <el-sub-menu index="/products">
            <template #title>
              <el-icon>
                <Goods />
              </el-icon>
              <span>商品管理</span>
            </template>
            <el-menu-item index="/products">商品列表</el-menu-item>
            <el-menu-item index="/products/category">商品分类</el-menu-item>
          </el-sub-menu>

          <el-sub-menu index="order">
            <template #title>
              <el-icon>
                <List />
              </el-icon>
              <span>订单管理</span>
            </template>
            <el-menu-item index="/orders">订单列表</el-menu-item>
          </el-sub-menu>

          <el-sub-menu index="user">
            <template #title>
              <el-icon>
                <User />
              </el-icon>
              <span>用户管理</span>
            </template>
            <el-menu-item index="/users">用户列表</el-menu-item>
          </el-sub-menu>

          <el-sub-menu index="rider">
            <template #title>
              <el-icon>
                <Van />
              </el-icon>
              <span>骑手管理</span>
            </template>
            <el-menu-item index="/riders">骑手列表</el-menu-item>
          </el-sub-menu>
        </el-menu>
      </el-scrollbar>
    </el-aside>

    <!-- 主体容器 -->
    <el-container class="main-container">
      <!-- 头部 -->
      <el-header class="header">
        <!-- 头部左侧 -->
        <div class="header-left">
          <!-- 关闭/展开 左侧导航栏按钮 -->
          <el-icon class="collapse-btn" @click="isCollapse = !isCollapse">
            <Fold v-if="!isCollapse" />
            <Expand v-else />
          </el-icon>
          <!-- 面包屑导航栏 -->
          <el-breadcrumb separator="/">
            <template v-for="(item, index) in breadcrumbs" :key="index">
              <el-breadcrumb-item :to="index === 0 ? '/' : undefined">
                {{ item }}
              </el-breadcrumb-item>
            </template>
          </el-breadcrumb>
        </div>

        <!-- 右边功能按钮 -->
        <div class="header-right">
          <el-space>
            <!-- 全屏按钮 -->
            <el-tooltip content="全屏" placement="bottom">
              <el-icon class="header-icon" @click="BaseUtils.toggleFullScreen()">
                <FullScreen />
              </el-icon>
            </el-tooltip>

            <!-- 消息 -->
            <el-dropdown trigger="click" @command="handleMessageClick">
              <div class="message-trigger">
                <el-badge :value="unreadCount" :hidden="!unreadCount" class="message-badge">
                  <el-icon class="header-icon">
                    <Bell />
                  </el-icon>
                </el-badge>
              </div>
              <!-- 下拉展示 -->
              <template #dropdown>
                <el-dropdown-menu class="message-dropdown">
                  <!-- 全部已读 -->
                  <div class="message-header">
                    <div class="header-left">
                      <span class="title">消息通知</span>
                      <el-tag size="small" type="danger" effect="plain" v-if="unreadCount">{{ unreadCount }}条未读</el-tag>
                    </div>
                    <el-button link type="primary" size="small"
                      @click.stop="MessageUtils.clear(); messages = []" :disabled="!unreadCount">
                      <el-icon>
                        <Close />
                      </el-icon>清空消息
                    </el-button>
                  </div>

                  <!-- 消息展示列表 -->
                  <div class="message-list">
                    <el-scrollbar height="800px">
                      <template v-if="messages.length">
                        <el-dropdown-item class="message-item" v-for="msg in messages" :key="msg.id" :command="msg"
                          :class="{ unread: !msg.isRead }">
                          <div class="message-content">
                            <div class="message-title">
                              <el-icon :class="MessageType.get(msg).class">
                                <component :is="MessageType.get(msg).icon" />
                              </el-icon>
                              <el-tag size="small" :type="MessageType.get(msg).tagType" effect="light" round>
                                {{ MessageType.get(msg).label }}
                              </el-tag>
                              <span>{{ msg.title }}</span>
                            </div>
                            <div class="message-brief">{{ msg.content }}</div>
                            <div class="message-footer">
                              <span class="message-time">{{ msg.time }}（{{ timeDifferences[msg.id] }}）</span>
                            </div>
                          </div>
                          <div class="message-dot" v-if="!msg.isRead" />
                        </el-dropdown-item>
                      </template>
                      <el-empty v-else description="暂无消息" :image-size="60" />
                    </el-scrollbar>
                  </div>
                </el-dropdown-menu>
              </template>
            </el-dropdown>

            <!-- 管理员 -->
            <el-dropdown trigger="click">
              <span class="user-info">
                <el-avatar :size="32" src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png" />
                <span class="user-name">{{ admin.name }}</span>
              </span>
              <template #dropdown v-if="admin.token != null">
                <el-dropdown-menu>
                  <el-dropdown-item @click.native="admin = {name: '', token: null}; AdminUtils.logout()">
                    <el-icon>
                      <SwitchButton />
                    </el-icon>退出登录
                  </el-dropdown-item>
                </el-dropdown-menu>
              </template>
            </el-dropdown>
          </el-space>
        </div>
      </el-header>

      <!-- 其它页面展示 -->
      <el-main class="main">
        <router-view v-slot="{ Component }" :key="key">
          <transition name="fade" mode="out-in">
            <component :is="Component" />
          </transition>
        </router-view>
      </el-main>
    </el-container>
  </el-container>

  <!-- 消息详情展示 -->
  <el-dialog v-model="messageDialog" :title="currentMessage?.title" width="500px" align-center destroy-on-close>
    <div class="message-detail">
      <div class="message-info">
        <el-tag size="small" :type="MessageType.get(currentMessage).tagType">
          {{ MessageType.get(currentMessage).label }}
        </el-tag>
        <span class="message-time">{{ currentMessage?.time }}</span>
      </div>
      <div class="message-body">{{ currentMessage?.content }}</div>
    </div>
  </el-dialog>
</template>

<script setup lang="ts">
import { AdminUtils } from '@/models/adminModel';
import { StatisticalData, StatisticalUtils } from '@/models/homeModel';
import { Message, MessageType, MessageUtils } from '@/models/messageModel';
import { useCounterSotre } from '@/store/counter';
import { BaseUtils } from '@/utils';
import { ref, computed, onMounted, onBeforeUnmount } from 'vue';
import { useRoute } from 'vue-router';

// 控制侧边栏是否关闭
const isCollapse = ref<boolean>(true)

// 管理员数据
const admin = AdminUtils.getAdmin()

// router
const route = useRoute()
// 当前激活的菜单
const activeMenu = computed(() => route.path)
// 标识（防止切换页面时，页面空白）
const key = computed(() => route.path + Math.random());
// 面包屑导航映射
const routeNames: Record<string, string[]> = {
  '/': ['首页'],
  '/products': ['商品管理', '商品列表'],
  '/products/category': ['商品管理', '商品分类'],
  '/orders': ['订单管理', '订单列表'],
  '/users': ['用户管理', '用户列表'],
  '/riders': ['骑手管理', '骑手列表'],
  '/login': ['登录']
}
// 面包屑导航
const breadcrumbs = computed(() => {
  return routeNames[route.path] || ['未知页面']
})

// 消息列表
const messages = ref<Message[]>(MessageUtils.getMessages())
// 当前选中的消息
const currentMessage = ref<Message | undefined>()
// 计算未读消息的数量
const unreadCount = computed(() => messages.value.filter(m => !m.isRead).length)
// 消息展示
const messageDialog = ref<boolean>(false)
// 消息时间计时
const timeDifferences = ref<Record<string, string>>({});
// 处理消息点击
const handleMessageClick = (message: Message) => {
  currentMessage.value = message
  messageDialog.value = true
  if (!message.isRead) message.isRead = true
  MessageUtils.setRead(message.id)
}
// 定时器
let timer: any

const store = useCounterSotre()

onMounted(() => {
  // 初始化消息计时
  messages.value.forEach((message) => {timeDifferences.value[message.id] = BaseUtils.timeAgo(message.time)})
  // 触发 watchEffect
  timer = setInterval(() => {
    const newDifferences: Record<string, string> = {};
    messages.value.forEach((message) => {newDifferences[message.id] = BaseUtils.timeAgo(message.time);});
    timeDifferences.value = newDifferences;
  }, 60 * 950);

  // 获取一遍数据
  StatisticalUtils.get((data: StatisticalData) => {
    store.statisticalData = data
  })

  // 建立 webStocket 链接
  const stock = new WebSocket("ws://localhost:8082/websocket")
  // 链接服务器
  stock.onopen = () => {console.log("链接成功");}

  // 当接收到信息时
  stock.onmessage = (event) => {
    let message = JSON.parse(event.data)    
    // 这是一个订单完成的消息
    if (message.code == 201) {
      // 更新 Home 页统计数据
      store.statisticalData = message.data
    }
    else if (message.code == 200) {
      // 这是一个支付了订单的消息【新增本地消息通知】
      MessageUtils.addMessage(message.data as Message, (data: Message[]) => {
        messages.value = data
      })      
    }
  }

  // 当链接断开时
  stock.onclose = () => {console.log("已断开链接");}
})

onBeforeUnmount(() => {
  // 组件销毁前清除定时器
  clearInterval(timer);
});
</script>

<style scoped>
.layout-container {
  height: 100vh;
  width: 100vw;
  overflow: hidden;
}

.aside {
  background-color: #304156;
  transition: width 0.3s;
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.main-container {
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.main {
  flex: 1;
  padding: 20px;
  height: calc(100vh - 60px);
  overflow: auto;
}

/* 设置滚动条样式 */
.main::-webkit-scrollbar {
  width: 6px;
}

.main::-webkit-scrollbar-thumb {
  background: #ccc;
  border-radius: 3px;
}

.main::-webkit-scrollbar-track {
  background: #f1f1f1;
}

.logo {
  height: 60px;
  min-height: 60px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 10px;
  background: #2b2f3a;
  overflow: hidden;
}

.logo-text,
.logo-text-collapse {
  color: #fff;
  font-size: 18px;
  font-weight: 600;
  white-space: nowrap;
  text-align: center;
}

.logo-text-collapse {
  font-size: 16px;
}

/* 确保菜单可以在侧边栏内滚动 */
.el-menu-vertical {
  border-right: none;
  flex: 1;
}

:deep(.el-scrollbar) {
  /* height: calc(100vh - 60px); */
}

:deep(.el-scrollbar__wrap) {
  overflow-x: hidden;
}

.header {
  height: 60px;
  min-height: 60px;
  background: #fff;
  border-bottom: 1px solid #ddd;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 20px;
  box-shadow: 0 1px 4px rgba(0, 21, 41, .08);
  position: relative;
  z-index: 999;
}

.header-left {
  display: flex;
  align-items: center;
}

.collapse-btn {
  font-size: 20px;
  cursor: pointer;
  margin-right: 20px;
  color: #666;
}

.collapse-btn:hover {
  color: #409EFF;
}

.header-right {
  display: flex;
  align-items: center;
}

.header-icon {
  font-size: 20px;
  color: #666;
  cursor: pointer;
  padding: 0 8px;
}

.header-icon:hover {
  color: #409EFF;
}

.notice-badge :deep(.el-badge__content) {
  z-index: 1001;
}

.user-info {
  display: flex;
  align-items: center;
  cursor: pointer;
  padding: 0 8px;
}

.user-name {
  margin-left: 8px;
  font-size: 14px;
  color: #666;
}

:deep(.el-menu) {
  border-right: none;
}

:deep(.el-sub-menu .el-menu-item) {
  min-width: 220px;
  background-color: #1f2d3d;
}

:deep(.el-menu-item:hover),
:deep(.el-sub-menu__title:hover) {
  background-color: #263445 !important;
}

:deep(.el-menu-item.is-active) {
  background-color: #263445 !important;
}

:deep(.el-dropdown-menu__item) {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* 路由切换动画 */
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

/* 可以添加面包屑的样式 */
:deep(.el-breadcrumb__item) {
  display: flex;
  align-items: center;
}

:deep(.el-breadcrumb__inner) {
  color: #606266;
  font-weight: normal;
}

:deep(.el-breadcrumb__inner.is-link) {
  color: #909399;
  font-weight: normal;
}

:deep(.el-breadcrumb__inner.is-link:hover) {
  color: var(--el-color-primary);
}

:deep(.el-breadcrumb__separator) {
  margin: 0 8px;
  color: #909399;
}

/* 添加消息相关样式 */
.message-dropdown {
  width: 380px;
  padding: 0;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.message-list {
  overflow: hidden;
  /* 防止滚动条溢出 */
}

/* 调整滚动条容器样式 */
:deep(.el-scrollbar) {
  overflow: hidden;
}

:deep(.el-scrollbar__wrap) {
  overflow-x: hidden;
}

:deep(.el-scrollbar__bar.is-horizontal) {
  display: none;
}

/* 美化滚动条 */
:deep(.el-scrollbar__thumb) {
  background-color: #dcdfe6;
  opacity: 0.3;
}

:deep(.el-scrollbar__thumb:hover) {
  opacity: 0.5;
}

/* 调整消息项样式 */
.message-item {
  padding: 12px 16px !important;
  margin: 0 !important;
  border-bottom: 1px solid #f0f2f5;
  transition: all 0.3s ease;
  height: auto !important;
  line-height: initial !important;
  /* 重置行高 */
}

.message-header {
  padding: 12px 16px;
  border-bottom: 1px solid #ebeef5;
  display: flex;
  justify-content: space-between;
  align-items: center;
  background-color: #fafafa;
  border-radius: 8px 8px 0 0;
}

.header-left {
  display: flex;
  align-items: center;
  gap: 8px;
}

.header-left .title {
  font-size: 14px;
  font-weight: 500;
  color: #303133;
}

.message-item {
  padding: 12px 16px !important;
  margin: 0 !important;
  border-bottom: 1px solid #f0f2f5;
  transition: all 0.3s ease;
  height: auto !important;
}

.message-item:hover {
  background-color: #f5f7fa !important;
}

.message-item:last-child {
  border-bottom: none;
}

.message-item.unread {
  background-color: var(--el-color-primary-light-9) !important;
}

.message-item.unread:hover {
  background-color: var(--el-color-primary-light-8) !important;
}

.message-content {
  position: relative;
  padding-right: 16px;
  min-width: 0;
}

.message-title {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  font-weight: 500;
  color: #303133;
  margin-bottom: 6px;
}

.message-icon {
  font-size: 14px;
  flex-shrink: 0;
}

.message-brief {
  font-size: 12px;
  color: #606266;
  margin-bottom: 8px;
  line-height: 1.5;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.message-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.message-time {
  font-size: 12px;
  color: #909399;
}

.message-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background-color: var(--el-color-danger);
  position: absolute;
  right: 20px;
  top: 8px;
}

/* 图标颜色 */
.info-icon {
  color: var(--el-color-primary);
}

.warning-icon {
  color: var(--el-color-warning);
}

.success-icon {
  color: var(--el-color-success);
}

/* 消息详情对话框样式 */
.message-detail {
  padding: 24px;
}

.message-info {
  margin-bottom: 20px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.message-body {
  font-size: 14px;
  line-height: 1.8;
  color: #606266;
  background-color: #fafafa;
  padding: 16px;
  border-radius: 4px;
}

:deep(.el-empty) {
  padding: 16px 0;
}

/* 调整标签大小 */
:deep(.el-tag--small) {
  height: 20px;
  padding: 0 8px;
  font-size: 11px;
}

/* 调整滚动条样式 */
:deep(.el-scrollbar__wrap) {
  margin-right: -8px !important;
  margin-bottom: -8px !important;
}

:deep(.el-scrollbar__thumb) {
  background-color: #dcdfe6;
  opacity: 0.3;
}

:deep(.el-scrollbar__thumb:hover) {
  opacity: 0.5;
}

/* 调整空状态样式 */
:deep(.el-empty) {
  padding: 24px 0;
}

:deep(.el-empty__description) {
  margin-top: 8px;
  color: #909399;
}

/* 添加消息徽标相关样式 */
.message-trigger {
  display: flex;
  align-items: center;
  cursor: pointer;
}

.message-badge {
  line-height: 1;
}

:deep(.el-badge__content) {
  height: 16px;
  padding: 0 4px;
  line-height: 16px;
  font-size: 12px;
  border: none;
}
</style>